<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>结果后处理 - 数据处理平台</title>
<script src="https://cdn.tailwindcss.com/3.4.16"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3b82f6',
secondary: '#6366f1'
},
borderRadius: {
'none': '0px',
'sm': '4px',
DEFAULT: '8px',
'md': '12px',
'lg': '16px',
'xl': '20px',
'2xl': '24px',
'3xl': '32px',
'full': '9999px',
'button': '8px'
}
}
}
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.6.0/remixicon.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
<style>
:where([class^="ri-"])::before {
content: "\f3c2";
}
.custom-checkbox {
appearance: none;
width: 1rem;
height: 1rem;
border: 2px solid #d1d5db;
border-radius: 0.25rem;
background-color: white;
cursor: pointer;
position: relative;
}
.custom-checkbox:checked {
background-color: #3b82f6;
border-color: #3b82f6;
}
.custom-checkbox:checked::after {
content: '';
position: absolute;
left: 3px;
top: 1px;
width: 4px;
height: 8px;
border: solid white;
border-width: 0 2px 2px 0;
transform: rotate(45deg);
}
.custom-switch {
width: 44px;
height: 24px;
background-color: #d1d5db;
border-radius: 12px;
position: relative;
cursor: pointer;
transition: background-color 0.3s;
}
.custom-switch.active {
background-color: #3b82f6;
}
.custom-switch::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background-color: white;
border-radius: 50%;
transition: transform 0.3s;
}
.custom-switch.active::after {
transform: translateX(20px);
}
.custom-range {
-webkit-appearance: none;
appearance: none;
width: 100%;
height: 6px;
border-radius: 3px;
background: #e5e7eb;
outline: none;
}
.custom-range::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #3b82f6;
cursor: pointer;
}
.custom-range::-moz-range-thumb {
width: 20px;
height: 20px;
border-radius: 50%;
background: #3b82f6;
cursor: pointer;
border: none;
}
.custom-radio {
appearance: none;
width: 1rem;
height: 1rem;
border: 2px solid #d1d5db;
border-radius: 50%;
background-color: white;
cursor: pointer;
position: relative;
}
.custom-radio:checked {
border-color: #3b82f6;
}
.custom-radio:checked::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #3b82f6;
}
.upload-area {
border: 2px dashed #d1d5db;
transition: all 0.3s ease;
}
.upload-area.dragover {
border-color: #3b82f6;
background-color: #eff6ff;
}
.step-item {
position: relative;
}
.step-item:not(:last-child)::after {
content: '';
position: absolute;
top: 50%;
right: -1rem;
width: 2rem;
height: 2px;
background-color: #e5e7eb;
transform: translateY(-50%);
}
.step-item.active::after {
background-color: #3b82f6;
}
.tool-button {
transition: all 0.2s ease;
}
.tool-button:hover {
transform: translateY(-1px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.tool-button.active {
border-color: #3b82f6;
background-color: #eff6ff;
}
.tab-button {
transition: all 0.2s ease;
}
.tab-button.active {
background-color: #3b82f6;
color: white;
}
</style>
</head>
<body class="bg-gray-50">
<div class="flex h-screen">
<aside class="w-64 bg-white shadow-sm border-r border-gray-200 flex flex-col">
<div class="p-4 border-b border-gray-200">
<div class="flex items-center">
<span class="text-xl font-bold text-gray-900 font-['Pacifico']">logo</span>
</div>
</div>
<nav class="flex-1 px-2 py-4">
<ul class="space-y-1">
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
<i class="ri-dashboard-line"></i>
</div>
<span>模型管理</span>
<div class="w-5 h-5 flex items-center justify-center ml-auto">
<i class="ri-arrow-right-s-line"></i>
</div>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
</div>
<span>模型生命周期</span>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
</div>
<span>模型性能评估</span>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
</div>
<span>模型转换适配</span>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
<i class="ri-cpu-line"></i>
</div>
<span>推理服务</span>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
<i class="ri-api-line"></i>
</div>
<span>API 接口</span>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm bg-primary text-white rounded-lg">
<div class="w-5 h-5 flex items-center justify-center mr-2">
<i class="ri-database-2-line"></i>
</div>
<span>数据处理</span>
<div class="w-5 h-5 flex items-center justify-center ml-auto">
<i class="ri-arrow-down-s-line"></i>
</div>
</button>
<ul class="ml-6 mt-2 space-y-1">
<li>
<a href="https://readdy.ai/home/42b69b4b-e314-4f8d-9e2f-98a4952face1/9378c72c-61c7-4d59-b808-6bd09795c82d" data-readdy="true" class="flex items-center w-full px-3 py-2 text-sm text-blue-200 hover:text-white hover:bg-blue-600 rounded-lg">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-filter-3-line"></i>
</div>
<span>数据预处理</span>
</a>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-blue-200 hover:text-white hover:bg-blue-600 rounded-lg">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-magic-line"></i>
</div>
<span>数据增强</span>
</button>
</li>
<li>
<button class="flex items-center w-full px-3 py-2 text-sm text-white bg-blue-600 rounded-lg">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-settings-3-line"></i>
</div>
<span>结果后处理</span>
</button>
</li>
</ul>
</li>
</ul>
</nav>
</aside>
<div class="flex-1 flex flex-col">
<header class="bg-white border-b border-gray-200 px-6 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<a href="https://readdy.ai/home/42b69b4b-e314-4f8d-9e2f-98a4952face1/89aef61f-e02e-4f74-9680-4a0d35936fdf" data-readdy="true" class="flex items-center text-gray-500 hover:text-gray-700">
<div class="w-5 h-5 flex items-center justify-center mr-2">
<i class="ri-arrow-left-line"></i>
</div>
<span class="text-sm">返回</span>
</a>
<nav class="text-sm text-gray-500">
<span>数据处理平台</span>
<span class="mx-2">/</span>
<span>数据处理</span>
<span class="mx-2">/</span>
<span class="text-gray-900">结果后处理</span>
</nav>
</div>
<div class="flex items-center space-x-4">
<div class="relative">
<select class="appearance-none bg-white border border-gray-300 rounded-lg px-4 py-2 pr-8 text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent">
<option>生产环境</option>
<option>测试环境</option>
<option>开发环境</option>
</select>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<i class="ri-arrow-down-s-line text-gray-400"></i>
</div>
</div>
<div class="relative">
<input type="text" placeholder="搜索任务..." class="bg-gray-50 border border-gray-300 rounded-lg pl-10 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent w-64">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<i class="ri-search-line text-gray-400"></i>
</div>
</div>
<button class="relative p-2 text-gray-400 hover:text-gray-600">
<div class="w-6 h-6 flex items-center justify-center">
<i class="ri-notification-3-line"></i>
</div>
<span class="absolute top-0 right-0 block h-2 w-2 rounded-full bg-red-500"></span>
</button>
<div class="flex items-center space-x-3">
<img src="https://readdy.ai/api/search-image?query=professional%20business%20portrait%20of%20a%20young%20asian%20software%20engineer%20in%20modern%20office%20setting%2C%20clean%20background%2C%20professional%20lighting%2C%20high%20quality%20headshot&width=40&height=40&seq=user_avatar&orientation=squarish" alt="用户头像" class="w-8 h-8 rounded-full object-cover">
<div class="text-sm">
<div class="text-gray-900 font-medium">张开发</div>
</div>
</div>
</div>
</div>
</header>
<main class="flex-1 overflow-auto">
<div class="p-6">
<div class="flex items-center justify-between mb-6">
<div>
<h1 class="text-2xl font-bold text-gray-900">结果后处理</h1>
<p class="text-gray-600 mt-1">对模型输出结果进行优化、格式化和可视化展示</p>
</div>
<div class="flex items-center space-x-3">
<button id="saveConfigBtn" class="bg-white border border-gray-300 text-gray-700 px-6 py-2 rounded-button text-sm font-medium hover:bg-gray-50 whitespace-nowrap !rounded-button flex items-center">
<i class="ri-save-line mr-2"></i>
保存配置
</button>
<button id="loadTemplateBtn" class="bg-white border border-gray-300 text-gray-700 px-6 py-2 rounded-button text-sm font-medium hover:bg-gray-50 whitespace-nowrap !rounded-button flex items-center">
<i class="ri-folder-open-line mr-2"></i>
加载模板
</button>
<button id="startProcessBtn" class="bg-primary text-white px-6 py-2 rounded-button text-sm font-medium hover:bg-blue-600 whitespace-nowrap !rounded-button flex items-center">
<i class="ri-play-line mr-2"></i>
开始处理
</button>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
<div class="bg-white rounded-lg p-6 shadow-sm border border-gray-200">
<div class="flex items-center">
<div class="w-12 h-12 flex items-center justify-center bg-blue-100 rounded-lg">
<i class="ri-file-list-3-line text-blue-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">待处理结果</p>
<p class="text-2xl font-bold text-gray-900">89</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg p-6 shadow-sm border border-gray-200">
<div class="flex items-center">
<div class="w-12 h-12 flex items-center justify-center bg-green-100 rounded-lg">
<i class="ri-check-double-line text-green-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">处理完成</p>
<p class="text-2xl font-bold text-gray-900">2,156</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg p-6 shadow-sm border border-gray-200">
<div class="flex items-center">
<div class="w-12 h-12 flex items-center justify-center bg-yellow-100 rounded-lg">
<i class="ri-timer-line text-yellow-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">平均处理时间</p>
<p class="text-2xl font-bold text-gray-900">1.8秒</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg p-6 shadow-sm border border-gray-200">
<div class="flex items-center">
<div class="w-12 h-12 flex items-center justify-center bg-purple-100 rounded-lg">
<i class="ri-dashboard-3-line text-purple-600 text-xl"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-600">系统资源使用</p>
<p class="text-2xl font-bold text-gray-900">72.3%</p>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-6">
<div class="lg:col-span-2 space-y-6">
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">结果导入区域</h2>
</div>
<div class="p-6">
<div id="resultUploadArea" class="upload-area rounded-lg p-8 text-center cursor-pointer">
<div class="w-16 h-16 flex items-center justify-center bg-gray-100 rounded-lg mx-auto mb-4">
<i class="ri-file-upload-line text-gray-400 text-2xl"></i>
</div>
<h3 class="text-lg font-medium text-gray-900 mb-2">导入模型输出结果</h3>
<p class="text-sm text-gray-500 mb-4">支持 JSON、XML、CSV、二进制文件等格式，单个文件最大 500MB</p>
<div class="flex items-center justify-center space-x-4">
<button id="selectResultBtn" class="bg-primary text-white px-4 py-2 rounded-button text-sm hover:bg-blue-600 !rounded-button">
选择结果文件
</button>
<button id="batchImportBtn" class="bg-white border border-gray-300 text-gray-700 px-4 py-2 rounded-button text-sm hover:bg-gray-50 !rounded-button">
批量导入
</button>
</div>
<input type="file" id="resultInput" class="hidden" multiple accept=".json,.xml,.csv,.txt,.bin,.pkl">
</div>
<div id="importedResults" class="mt-4 space-y-2 hidden">
<h4 class="text-sm font-medium text-gray-700 mb-2">已导入结果</h4>
<div class="space-y-2" id="resultList">
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<div class="w-8 h-8 flex items-center justify-center bg-green-100 rounded-lg mr-3">
<i class="ri-file-text-line text-green-600"></i>
</div>
<div>
<div class="text-sm font-medium text-gray-900">model_output_20241022.json</div>
<div class="text-xs text-gray-500">2.45 MB • 包含 1,245 条预测结果</div>
</div>
</div>
<button class="text-red-500 hover:text-red-700">
<i class="ri-delete-bin-line"></i>
</button>
</div>
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<div class="w-8 h-8 flex items-center justify-center bg-blue-100 rounded-lg mr-3">
<i class="ri-file-code-line text-blue-600"></i>
</div>
<div>
<div class="text-sm font-medium text-gray-900">inference_results.xml</div>
<div class="text-xs text-gray-500">1.87 MB • 包含 892 条分类结果</div>
</div>
</div>
<button class="text-red-500 hover:text-red-700">
<i class="ri-delete-bin-line"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<h2 class="text-lg font-semibold text-gray-900">后处理工具栏</h2>
<button id="resetToolsBtn" class="text-sm text-gray-500 hover:text-gray-700">
<i class="ri-refresh-line mr-1"></i>
重置
</button>
</div>
</div>
<div class="p-6">
<div class="grid grid-cols-2 gap-4">
<button class="tool-button flex flex-col items-center p-4 border-2 border-gray-200 rounded-lg hover:border-primary" data-tool="filter">
<div class="w-10 h-10 flex items-center justify-center bg-blue-100 rounded-lg mb-2">
<i class="ri-filter-2-line text-blue-600"></i>
</div>
<span class="text-sm font-medium text-gray-900">结果筛选</span>
<span class="text-xs text-gray-500 mt-1">数据过滤和阈值设置</span>
</button>
<button class="tool-button flex flex-col items-center p-4 border-2 border-gray-200 rounded-lg hover:border-primary" data-tool="convert">
<div class="w-10 h-10 flex items-center justify-center bg-green-100 rounded-lg mb-2">
<i class="ri-exchange-line text-green-600"></i>
</div>
<span class="text-sm font-medium text-gray-900">格式转换</span>
<span class="text-xs text-gray-500 mt-1">输出格式和编码转换</span>
</button>
<button class="tool-button flex flex-col items-center p-4 border-2 border-gray-200 rounded-lg hover:border-primary" data-tool="visualize">
<div class="w-10 h-10 flex items-center justify-center bg-purple-100 rounded-lg mb-2">
<i class="ri-bar-chart-line text-purple-600"></i>
</div>
<span class="text-sm font-medium text-gray-900">可视化图表</span>
<span class="text-xs text-gray-500 mt-1">生成图表和报告</span>
</button>
<button class="tool-button flex flex-col items-center p-4 border-2 border-gray-200 rounded-lg hover:border-primary" data-tool="validate">
<div class="w-10 h-10 flex items-center justify-center bg-orange-100 rounded-lg mb-2">
<i class="ri-shield-check-line text-orange-600"></i>
</div>
<span class="text-sm font-medium text-gray-900">结果验证</span>
<span class="text-xs text-gray-500 mt-1">准确性和一致性检查</span>
</button>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">工具配置面板</h2>
</div>
<div class="p-6">
<div id="toolConfigPanel" class="space-y-4">
<div class="p-4 bg-gray-50 rounded-lg">
<p class="text-sm text-gray-600">请选择后处理工具来配置参数</p>
</div>
</div>
</div>
</div>
</div>
<div class="space-y-6">
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<div class="flex items-center justify-between">
<h2 class="text-lg font-semibold text-gray-900">处理效果预览</h2>
<div class="flex items-center space-x-2">
<button class="tab-button px-3 py-1 text-sm rounded-full bg-primary text-white" data-view="table">表格视图</button>
<button class="tab-button px-3 py-1 text-sm rounded-full bg-gray-200 text-gray-700" data-view="chart">图表视图</button>
</div>
</div>
</div>
<div class="p-6">
<div id="previewContent">
<div class="grid grid-cols-2 gap-6">
<div>
<h4 class="text-sm font-medium text-gray-700 mb-3">原始结果</h4>
<div class="border border-gray-200 rounded-lg p-4 bg-gray-50 min-h-[200px]">
<div class="space-y-2 text-sm">
<div class="flex justify-between"><span class="text-gray-600">预测类别:</span><span>猫</span></div>
<div class="flex justify-between"><span class="text-gray-600">置信度:</span><span>0.8945</span></div>
<div class="flex justify-between"><span class="text-gray-600">边界框:</span><span>[120, 80, 340, 260]</span></div>
<div class="flex justify-between"><span class="text-gray-600">处理时间:</span><span>45ms</span></div>
</div>
</div>
</div>
<div>
<h4 class="text-sm font-medium text-gray-700 mb-3">处理后结果</h4>
<div class="border border-gray-200 rounded-lg p-4 bg-blue-50 min-h-[200px]">
<div class="space-y-2 text-sm">
<div class="flex justify-between"><span class="text-gray-600">预测类别:</span><span class="font-medium">猫 (Cat)</span></div>
<div class="flex justify-between"><span class="text-gray-600">置信度:</span><span class="text-green-600 font-medium">89.45%</span></div>
<div class="flex justify-between"><span class="text-gray-600">边界框:</span><span>[x:120, y:80, w:220, h:180]</span></div>
<div class="flex justify-between"><span class="text-gray-600">标准化得分:</span><span class="text-blue-600 font-medium">A级</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">可视化展示区域</h2>
</div>
<div class="p-6">
<div id="chartContainer" style="width: 100%; height: 300px;"></div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">处理进度监控</h2>
</div>
<div class="p-6">
<div class="space-y-4">
<div class="flex items-center justify-between">
<span class="text-sm text-gray-600">总体进度</span>
<span class="text-sm font-medium text-gray-900" id="progressPercent">0%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div id="overallProgress" class="bg-primary h-2 rounded-full transition-all duration-300" style="width: 0%"></div>
</div>
<div class="space-y-2">
<div class="flex items-center justify-between text-sm">
<span class="text-gray-600">结果筛选</span>
<span class="text-gray-500" id="filterStatus">待开始</span>
</div>
<div class="flex items-center justify-between text-sm">
<span class="text-gray-600">格式转换</span>
<span class="text-gray-500" id="convertStatus">待开始</span>
</div>
<div class="flex items-center justify-between text-sm">
<span class="text-gray-600">可视化生成</span>
<span class="text-gray-500" id="visualizeStatus">待开始</span>
</div>
<div class="flex items-center justify-between text-sm">
<span class="text-gray-600">结果验证</span>
<span class="text-gray-500" id="validateStatus">待开始</span>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">批量处理设置</h2>
</div>
<div class="p-6">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">批处理大小</label>
<input type="range" class="custom-range" min="10" max="1000" value="200" id="batchSizeSlider">
<div class="flex justify-between text-xs text-gray-500 mt-1">
<span>10</span>
<span id="batchSizeValue">200</span>
<span>1000</span>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">并发处理线程</label>
<div class="relative">
<select class="appearance-none w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent pr-8">
<option>2</option>
<option>4</option>
<option selected>8</option>
<option>16</option>
<option>32</option>
</select>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<i class="ri-arrow-down-s-line text-gray-400"></i>
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">错误处理策略</label>
<div class="space-y-2">
<label class="flex items-center">
<input type="radio" class="custom-radio mr-2" name="errorStrategy" value="skip" checked>
<span class="text-sm text-gray-700">跳过错误继续处理</span>
</label>
<label class="flex items-center">
<input type="radio" class="custom-radio mr-2" name="errorStrategy" value="stop">
<span class="text-sm text-gray-700">遇到错误时停止</span>
</label>
<label class="flex items-center">
<input type="radio" class="custom-radio mr-2" name="errorStrategy" value="retry">
<span class="text-sm text-gray-700">自动重试失败项</span>
</label>
</div>
</div>
<div>
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-2" checked>
<span class="text-sm text-gray-700">保存处理日志</span>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-sm border border-gray-200">
<div class="p-6 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">处理日志</h2>
</div>
<div class="p-6">
<div id="logArea" class="bg-gray-900 text-green-400 p-4 rounded-lg font-mono text-sm h-48 overflow-y-auto">
<div class="text-gray-500">[系统] 结果后处理系统已就绪</div>
<div class="text-gray-500">[系统] 等待结果文件导入...</div>
<div class="text-blue-400">[信息] 已加载 2 个结果文件</div>
<div class="text-green-400">[成功] 模型输出结果验证通过</div>
</div>
</div>
</div>
</div>
</div>
<div class="fixed bottom-0 left-64 right-0 bg-white border-t border-gray-200 px-6 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<div class="text-sm text-gray-600">
已选择 <span id="selectedResultCount">2</span> 个结果文件
</div>
<div class="text-sm text-gray-600">
预计处理时间: <span id="estimatedTime">3.2 分钟</span>
</div>
</div>
<div class="flex items-center space-x-3">
<button id="clearAllBtn" class="bg-white border border-gray-300 text-gray-700 px-4 py-2 rounded-button text-sm hover:bg-gray-50 !rounded-button">
清空全部
</button>
<button id="exportResultBtn" class="bg-white border border-gray-300 text-gray-700 px-4 py-2 rounded-button text-sm hover:bg-gray-50 !rounded-button">
<i class="ri-download-line mr-2"></i>
导出结果
</button>
<button id="applyProcessBtn" class="bg-primary text-white px-6 py-2 rounded-button text-sm font-medium hover:bg-blue-600 !rounded-button">
<i class="ri-play-line mr-2"></i>
应用处理
</button>
</div>
</div>
</div>
<div id="configModal" class="fixed inset-0 bg-black bg-opacity-50 hidden flex items-center justify-center z-50">
<div class="bg-white rounded-lg w-[600px] shadow-xl">
<div class="px-6 py-4 border-b border-gray-200 flex items-center justify-between">
<h3 class="text-lg font-semibold text-gray-900">保存处理配置</h3>
<button id="closeConfigModal" class="text-gray-400 hover:text-gray-600">
<div class="w-5 h-5 flex items-center justify-center">
<i class="ri-close-line"></i>
</div>
</button>
</div>
<div class="p-6">
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">配置名称</label>
<input type="text" id="configName" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入配置名称">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">配置描述</label>
<textarea id="configDesc" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" placeholder="请输入配置描述"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">适用场景</label>
<div class="grid grid-cols-2 gap-2">
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-2">
<span class="text-sm text-gray-700">图像分类</span>
</label>
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-2">
<span class="text-sm text-gray-700">目标检测</span>
</label>
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-2">
<span class="text-sm text-gray-700">文本分析</span>
</label>
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-2">
<span class="text-sm text-gray-700">语音识别</span>
</label>
</div>
</div>
</div>
</div>
<div class="px-6 py-4 border-t border-gray-200 flex justify-end space-x-3">
<button id="cancelConfigBtn" class="px-4 py-2 border border-gray-300 rounded-button text-sm text-gray-700 hover:bg-gray-50">取消</button>
<button id="saveConfigConfirmBtn" class="px-4 py-2 bg-primary text-white rounded-button text-sm hover:bg-blue-600">保存配置</button>
</div>
</div>
</div>
<script id="resultImport">
document.addEventListener('DOMContentLoaded', function() {
const resultUploadArea = document.getElementById('resultUploadArea');
const resultInput = document.getElementById('resultInput');
const selectResultBtn = document.getElementById('selectResultBtn');
const batchImportBtn = document.getElementById('batchImportBtn');
const importedResults = document.getElementById('importedResults');
const resultList = document.getElementById('resultList');
const selectedResultCount = document.getElementById('selectedResultCount');
const logArea = document.getElementById('logArea');
let results = [];
function addLog(message, type = 'info') {
const timestamp = new Date().toLocaleTimeString();
const logEntry = document.createElement('div');
logEntry.className = type === 'error' ? 'text-red-400' : type === 'success' ? 'text-green-400' : 'text-gray-300';
logEntry.textContent = `[${timestamp}] ${message}`;
logArea.appendChild(logEntry);
logArea.scrollTop = logArea.scrollHeight;
}
function updateResultCount() {
selectedResultCount.textContent = results.length;
document.getElementById('applyProcessBtn').disabled = results.length === 0;
document.getElementById('exportResultBtn').disabled = results.length === 0;
}
function handleResultFiles(selectedFiles) {
Array.from(selectedFiles).forEach(file => {
if (file.size > 500 * 1024 * 1024) {
addLog(`文件 ${file.name} 超过 500MB 限制`, 'error');
return;
}
results.push(file);
addLog(`已导入结果文件: ${file.name}`, 'success');
});
updateResultCount();
importedResults.classList.remove('hidden');
}
resultUploadArea.addEventListener('dragover', function(e) {
e.preventDefault();
resultUploadArea.classList.add('dragover');
});
resultUploadArea.addEventListener('dragleave', function(e) {
e.preventDefault();
resultUploadArea.classList.remove('dragover');
});
resultUploadArea.addEventListener('drop', function(e) {
e.preventDefault();
resultUploadArea.classList.remove('dragover');
handleResultFiles(e.dataTransfer.files);
});
selectResultBtn.addEventListener('click', function() {
resultInput.click();
});
resultInput.addEventListener('change', function() {
handleResultFiles(this.files);
});
batchImportBtn.addEventListener('click', function() {
resultInput.setAttribute('webkitdirectory', '');
resultInput.click();
});
});
</script>
<script id="toolConfiguration">
document.addEventListener('DOMContentLoaded', function() {
const toolButtons = document.querySelectorAll('.tool-button');
const toolConfigPanel = document.getElementById('toolConfigPanel');
const resetToolsBtn = document.getElementById('resetToolsBtn');
let selectedTools = [];
const toolConfigs = {
filter: {
title: '结果筛选配置',
options: [
{ label: '置信度阈值', type: 'range', min: 0, max: 1, value: 0.8, step: 0.01 },
{ label: '筛选条件', type: 'select', options: ['大于阈值', '小于阈值', '区间范围'], value: '大于阈值' },
{ label: '保留前N个结果', type: 'number', value: 100 },
{ label: '去除重复结果', type: 'checkbox', checked: true }
]
},
convert: {
title: '格式转换配置',
options: [
{ label: '输出格式', type: 'select', options: ['JSON', 'XML', 'CSV', 'Excel', 'PDF报告'], value: 'JSON' },
{ label: '编码方式', type: 'select', options: ['UTF-8', 'GBK', 'ASCII'], value: 'UTF-8' },
{ label: '压缩输出', type: 'checkbox', checked: false },
{ label: '包含元数据', type: 'checkbox', checked: true }
]
},
visualize: {
title: '可视化配置',
options: [
{ label: '图表类型', type: 'select', options: ['柱状图', '折线图', '饼图', '散点图', '热力图'], value: '柱状图' },
{ label: '图表主题', type: 'select', options: ['默认', '深色', '简约', '彩色'], value: '默认' },
{ label: '显示数据标签', type: 'checkbox', checked: true },
{ label: '生成交互式图表', type: 'checkbox', checked: false }
]
},
validate: {
title: '结果验证配置',
options: [
{ label: '验证方式', type: 'select', options: ['统计检验', '交叉验证', '人工审核', '规则检查'], value: '统计检验' },
{ label: '验证严格度', type: 'select', options: ['宽松', '标准', '严格'], value: '标准' },
{ label: '生成验证报告', type: 'checkbox', checked: true },
{ label: '标记异常结果', type: 'checkbox', checked: true }
]
}
};
function renderToolConfig() {
if (selectedTools.length === 0) {
toolConfigPanel.innerHTML = `
<div class="p-4 bg-gray-50 rounded-lg">
<p class="text-sm text-gray-600">请选择后处理工具来配置参数</p>
</div>
`;
return;
}
toolConfigPanel.innerHTML = '';
selectedTools.forEach(tool => {
const config = toolConfigs[tool];
const toolDiv = document.createElement('div');
toolDiv.className = 'p-4 border border-gray-200 rounded-lg';
toolDiv.innerHTML = `
<h4 class="text-md font-medium text-gray-900 mb-3">${config.title}</h4>
<div class="space-y-3">
${config.options.map((option, index) => {
if (option.type === 'checkbox') {
return `
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-2" ${option.checked ? 'checked' : ''}>
<span class="text-sm text-gray-700">${option.label}</span>
</label>
`;
} else if (option.type === 'select') {
return `
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">${option.label}</label>
<div class="relative">
<select class="appearance-none w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent pr-8">
${option.options.map(opt => `<option ${opt === option.value ? 'selected' : ''}>${opt}</option>`).join('')}
</select>
<div class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
<i class="ri-arrow-down-s-line text-gray-400"></i>
</div>
</div>
</div>
`;
} else if (option.type === 'range') {
return `
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">${option.label}</label>
<input type="range" class="custom-range" min="${option.min}" max="${option.max}" value="${option.value}" step="${option.step || 1}">
<div class="flex justify-between text-xs text-gray-500 mt-1">
<span>${option.min}</span>
<span>${option.value}</span>
<span>${option.max}</span>
</div>
</div>
`;
} else if (option.type === 'number') {
return `
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">${option.label}</label>
<input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent" value="${option.value}">
</div>
`;
}
}).join('')}
</div>
`;
toolConfigPanel.appendChild(toolDiv);
});
}
toolButtons.forEach(button => {
button.addEventListener('click', function() {
const tool = this.dataset.tool;
if (selectedTools.includes(tool)) {
selectedTools = selectedTools.filter(t => t !== tool);
this.classList.remove('active');
} else {
selectedTools.push(tool);
this.classList.add('active');
}
renderToolConfig();
});
});
resetToolsBtn.addEventListener('click', function() {
selectedTools = [];
toolButtons.forEach(btn => btn.classList.remove('active'));
renderToolConfig();
});
});
</script>
<script id="chartVisualization">
document.addEventListener('DOMContentLoaded', function() {
const chartContainer = document.getElementById('chartContainer');
const tabButtons = document.querySelectorAll('.tab-button');
const previewContent = document.getElementById('previewContent');
const chart = echarts.init(chartContainer);
const chartOption = {
animation: false,
title: {
text: '模型预测结果分布',
textStyle: { color: '#1f2937' }
},
tooltip: {
trigger: 'item',
backgroundColor: 'rgba(255, 255, 255, 0.9)',
borderColor: '#e5e7eb',
textStyle: { color: '#1f2937' }
},
legend: {
orient: 'vertical',
left: 'left',
textStyle: { color: '#1f2937' }
},
series: [
{
name: '预测类别',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: '猫', itemStyle: { color: 'rgba(87, 181, 231, 1)' } },
{ value: 735, name: '狗', itemStyle: { color: 'rgba(141, 211, 199, 1)' } },
{ value: 580, name: '鸟', itemStyle: { color: 'rgba(251, 191, 114, 1)' } },
{ value: 484, name: '鱼', itemStyle: { color: 'rgba(252, 141, 98, 1)' } }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
],
grid: { top: 0, bottom: 0, left: 0, right: 0 }
};
chart.setOption(chartOption);
tabButtons.forEach(button => {
button.addEventListener('click', function() {
const view = this.dataset.view;
tabButtons.forEach(btn => {
btn.classList.remove('active', 'bg-primary', 'text-white');
btn.classList.add('bg-gray-200', 'text-gray-700');
});
this.classList.remove('bg-gray-200', 'text-gray-700');
this.classList.add('active', 'bg-primary', 'text-white');
if (view === 'chart') {
previewContent.innerHTML = '<div id="chartView" style="width: 100%; height: 400px;"></div>';
const newChart = echarts.init(document.getElementById('chartView'));
newChart.setOption(chartOption);
} else {
previewContent.innerHTML = `
<div class="grid grid-cols-2 gap-6">
<div>
<h4 class="text-sm font-medium text-gray-700 mb-3">原始结果</h4>
<div class="border border-gray-200 rounded-lg p-4 bg-gray-50 min-h-[200px]">
<div class="space-y-2 text-sm">
<div class="flex justify-between"><span class="text-gray-600">预测类别:</span><span>猫</span></div>
<div class="flex justify-between"><span class="text-gray-600">置信度:</span><span>0.8945</span></div>
<div class="flex justify-between"><span class="text-gray-600">边界框:</span><span>[120, 80, 340, 260]</span></div>
<div class="flex justify-between"><span class="text-gray-600">处理时间:</span><span>45ms</span></div>
</div>
</div>
</div>
<div>
<h4 class="text-sm font-medium text-gray-700 mb-3">处理后结果</h4>
<div class="border border-gray-200 rounded-lg p-4 bg-blue-50 min-h-[200px]">
<div class="space-y-2 text-sm">
<div class="flex justify-between"><span class="text-gray-600">预测类别:</span><span class="font-medium">猫 (Cat)</span></div>
<div class="flex justify-between"><span class="text-gray-600">置信度:</span><span class="text-green-600 font-medium">89.45%</span></div>
<div class="flex justify-between"><span class="text-gray-600">边界框:</span><span>[x:120, y:80, w:220, h:180]</span></div>
<div class="flex justify-between"><span class="text-gray-600">标准化得分:</span><span class="text-blue-600 font-medium">A级</span></div>
</div>
</div>
</div>
</div>
`;
}
});
});
chart.setOption(chartOption);
window.addEventListener('resize', function() {
chart.resize();
});
});
</script>
<script id="processControl">
document.addEventListener('DOMContentLoaded', function() {
const startProcessBtn = document.getElementById('startProcessBtn');
const applyProcessBtn = document.getElementById('applyProcessBtn');
const clearAllBtn = document.getElementById('clearAllBtn');
const exportResultBtn = document.getElementById('exportResultBtn');
const overallProgress = document.getElementById('overallProgress');
const progressPercent = document.getElementById('progressPercent');
const logArea = document.getElementById('logArea');
const batchSizeSlider = document.getElementById('batchSizeSlider');
const batchSizeValue = document.getElementById('batchSizeValue');
function addLog(message, type = 'info') {
const timestamp = new Date().toLocaleTimeString();
const logEntry = document.createElement('div');
logEntry.className = type === 'error' ? 'text-red-400' : type === 'success' ? 'text-green-400' : 'text-gray-300';
logEntry.textContent = `[${timestamp}] ${message}`;
logArea.appendChild(logEntry);
logArea.scrollTop = logArea.scrollHeight;
}
function updateProgress(progress) {
overallProgress.style.width = progress + '%';
progressPercent.textContent = Math.round(progress) + '%';
}
function simulateProcessing() {
let progress = 0;
const steps = ['filterStatus', 'convertStatus', 'visualizeStatus', 'validateStatus'];
const stepNames = ['结果筛选', '格式转换', '可视化生成', '结果验证'];
let currentStep = 0;
const interval = setInterval(() => {
progress += Math.random() * 8 + 2;
if (progress >= 100) {
progress = 100;
clearInterval(interval);
addLog('结果后处理完成', 'success');
exportResultBtn.disabled = false;
document.getElementById('validateStatus').textContent = '已完成';
document.getElementById('validateStatus').className = 'text-green-600';
} else {
const stepProgress = Math.floor(progress / 25);
if (stepProgress > currentStep && currentStep < steps.length) {
if (currentStep > 0) {
document.getElementById(steps[currentStep - 1]).textContent = '已完成';
document.getElementById(steps[currentStep - 1]).className = 'text-green-600';
}
document.getElementById(steps[currentStep]).textContent = '处理中...';
document.getElementById(steps[currentStep]).className = 'text-blue-600';
addLog(`开始${stepNames[currentStep]}...`, 'success');
currentStep++;
}
}
updateProgress(progress);
}, 300);
}
startProcessBtn.addEventListener('click', function() {
addLog('开始结果后处理...', 'success');
simulateProcessing();
});
applyProcessBtn.addEventListener('click', function() {
addLog('应用后处理配置...', 'success');
simulateProcessing();
});
clearAllBtn.addEventListener('click', function() {
if (confirm('确定要清空所有结果文件吗？')) {
addLog('已清空所有结果文件');
document.getElementById('selectedResultCount').textContent = '0';
}
});
exportResultBtn.addEventListener('click', function() {
addLog('正在导出处理结果...', 'success');
setTimeout(() => {
addLog('结果导出完成', 'success');
}, 1000);
});
batchSizeSlider.addEventListener('input', function() {
batchSizeValue.textContent = this.value;
});
});
</script>
<script id="configManagement">
document.addEventListener('DOMContentLoaded', function() {
const saveConfigBtn = document.getElementById('saveConfigBtn');
const loadTemplateBtn = document.getElementById('loadTemplateBtn');
const configModal = document.getElementById('configModal');
const closeConfigModal = document.getElementById('closeConfigModal');
const cancelConfigBtn = document.getElementById('cancelConfigBtn');
const saveConfigConfirmBtn = document.getElementById('saveConfigConfirmBtn');
function openConfigModal() {
configModal.classList.remove('hidden');
document.body.style.overflow = 'hidden';
}
function closeModal() {
configModal.classList.add('hidden');
document.body.style.overflow = '';
}
saveConfigBtn.addEventListener('click', openConfigModal);
closeConfigModal.addEventListener('click', closeModal);
cancelConfigBtn.addEventListener('click', closeModal);
configModal.addEventListener('click', function(e) {
if (e.target === this) {
closeModal();
}
});
saveConfigConfirmBtn.addEventListener('click', function() {
const configName = document.getElementById('configName').value;
if (!configName) {
alert('请输入配置名称');
return;
}
closeModal();
const notification = document.createElement('div');
notification.className = 'fixed top-4 right-4 bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg z-50';
notification.innerHTML = `配置 "${configName}" 保存成功`;
document.body.appendChild(notification);
setTimeout(() => {
notification.remove();
}, 3000);
});
});
</script>
</body>
</html>